<!DOCTYPE html>
<html lang="ch-CN">
<head>
    <meta charset="UTF-8">
    <title>this应用</title>
</head>
<style>
    body {
        width: 100%;
        height: 100vh;
        background-color: wheat;
        font-size: 30px;
        text-decoration: none;
        font-family: "华文楷体";
    }
</style>
<script>
    /*  在调用函数时，浏览器每次都会传递进两个隐含参数：
             * 1：函数的上下文对象----this
             * 2：封装实参的对象----arguments
    */

    /*
      * this指的是一个对象
      * 调用方式不同，this指向的对象也不同
      *   1：以函数的形式调用时，this指向的永远是window
      *   2：以方法的形式调用时，this就是调用方法的那个对象
      *   3：以构造函数形式调用时,this就是新创建的这个对象
      *   4：使用call(obj)和apply(obj)方法调用时，this就是方法中’obj‘指定的对象
    */

    //创建函数
    function fun() {
        document.write(this.text + this.name + this.age + "<br>")
    }

    //1:  以方法形式调用
    {
        let obj = {
            name: "小芳",
            age: "13",
            text: "1:方法的形式调用：",
            sayName: fun
        }
        /*document.write(obj.sayName == fun)  值为true 说明把fun这个对象赋值给了obj.sayName
          * 所以obj调用sayName()方法就相当于调用了fun()这个函数对象
          * 所以fun()函数中的this指的是调用他的这个对象
         */
        //以方法形式调用
        obj.sayName();
    }
    //2:  以函数形式调用
    {
        // window中的变量
        var name = "小红";
        var age = 100;
        var text = "2:函数的形式调用：";
        fun();
    }
    //3:  以构造函数的形式调用
    {
        //创建构造函数
        function Person(name, age, text) {
            this.name = name
                this.age = age
                this.text = text
        }

        //向构造函数的原型中添加一个system方法
        Person.prototype.system = function () {
            return this.text + "我是" + this.name + "今年" + age + "岁"
        }
        //对象实例化
        let person1 = new Person("张三", 12, "3:构造函数的形式调用：")
        //调用方法
        document.write(person1.system())
    }
    //4： 以函数的call(obj)和apply(obj)方法调用
    {
        function alt(age, gender) {
            document.write("<br>" + this.text + this.name + "性别" + age + "今年" + gender + "岁！！")
        }

        //定义一个对象test
        const test = {
            name: "我是张三",
            text: "4:(1):以函数的call()方法调用：",
            test_Fun: function () {
                alert(this.name)
            }
        }
        // 定义一个对象test1
        const test1 = {
            name: "我是李四",
            text: "4:(2):以函数的apply()方法调用："
        }

        //函数调用
        alt.call(test, "男", 22)
        alt.apply(test1, ["女", 12])
    }
</script>
<body>
</body>
</html>